package com.example.demo.controller;

import com.example.demo.bean.FileBean;
import com.example.demo.bean.StudentFileBean;
import com.example.demo.bean.TimetableBean;
import com.example.demo.service.FileService;
import com.example.demo.service.TimetableService;
import com.example.demo.utils.BaseResponse;
import com.example.demo.utils.SystemStatusEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * @author zhangbiao
 * @date 2020/6/25 8:14
 * @desc 描述
 */
@CrossOrigin
@Api(tags = "文件上传接口")
@RestController
public class UploaderController extends BaseController {

    @Value("${web.upload-path}")
    private String path;

    @Value("${web.image-path}")
    private String imagePath;

    //还要配置拦截器 WebConfigurer
    @Value("${server.servlet.context-path}")
    private String context_path;

    @Autowired
    private FileService fileService;
    /*
     *采用spring提供的上传文件的方法
     */
    @ApiOperation(value = "单个文件上传", nickname = "xxxx", notes = "文件上传接口")
//    @RequestMapping注解是用来映射请求的，即指明处理器可以处理哪些URL请求
    @RequestMapping(value = "springUpload", method = {RequestMethod.POST})
    public BaseResponse springUpload(@RequestParam("file") MultipartFile file,
                                     @RequestParam(name = "endtime") @ApiParam("截止时间") String endtime,
                                     @RequestParam(name = "timetable_id") @ApiParam("课程Id") String timetable_id) throws IOException {
        Map<String, String> map = new HashMap<>();
        BaseResponse result = new BaseResponse();
        String origName = file.getOriginalFilename();
        long startTime = System.currentTimeMillis();
        System.out.println("fileName：" + file.getOriginalFilename() + "==" + file.getContentType());
        String fileName = "file_" + new Date().getTime() + origName.substring(origName.indexOf("."), origName.length());

        String path = this.path + fileName;

        System.out.println("path="+path);

        File file1 = new File(this.path);
        if (!file1.exists()) {
            boolean end = file1.mkdirs();
            System.out.println("end=" + end);
        }
        File newFile = new File(path);
        if (!newFile.exists()) {
            newFile.createNewFile();
        }
        file.transferTo(newFile);
        System.out.println("filePath=" + newFile.getPath());
        long endTime = System.currentTimeMillis();
        System.out.println("方法二的运行时间：" + String.valueOf(endTime - startTime) + "ms");
        map.put("filename", fileName);
//        map.put("url", getServerIPPort(request) + context_path + imagePath + fileName);
        map.put("url", context_path + imagePath + fileName);
        map.put("origname", origName);
        //保存到数据库
        FileBean fileBean = getEntityFromRequest(FileBean.class);
        fileBean.setFilename(fileName);
        fileBean.setUrl(context_path + imagePath + fileName);
        fileBean.setOrigname(origName);
        fileBean.setEndtime(endtime);
        fileBean.setTimetable_id(timetable_id);
        fileService.addFile(fileBean);

        result.setCode(SystemStatusEnum.SUCCESS.getCode());
        result.setMessage("上传成功");
        result.setData(map);
        return result;
    }
    @ApiOperation(value = "学生文件上传", nickname = "xxxx", notes = "学生文件上传")
//    @RequestMapping注解是用来映射请求的，即指明处理器可以处理哪些URL请求
    @RequestMapping(value = "springUploadStudent", method = {RequestMethod.POST})
    public BaseResponse springUploadStudent(@RequestParam("file") MultipartFile file,
                                     @RequestParam(name = "endtime") @ApiParam("截止时间") String endtime,
                                     @RequestParam(name = "timetable_id") @ApiParam("课程Id") String timetable_id,
                                     @RequestParam(name = "student_id") @ApiParam("学生Id") String student_id) throws IOException {
        Map<String, String> map = new HashMap<>();
        BaseResponse result = new BaseResponse();
        String origName = file.getOriginalFilename();
        long startTime = System.currentTimeMillis();
        System.out.println("fileName：" + file.getOriginalFilename() + "==" + file.getContentType());
        String fileName = "file_" + new Date().getTime() + origName.substring(origName.indexOf("."), origName.length());

        String path = this.path + fileName;

        System.out.println("path="+path);

        File file1 = new File(this.path);
        if (!file1.exists()) {
            boolean end = file1.mkdirs();
            System.out.println("end=" + end);
        }
        File newFile = new File(path);
        if (!newFile.exists()) {
            newFile.createNewFile();
        }
        file.transferTo(newFile);
        System.out.println("filePath=" + newFile.getPath());
        long endTime = System.currentTimeMillis();
        System.out.println("方法二的运行时间：" + String.valueOf(endTime - startTime) + "ms");
        map.put("filename", fileName);
//        map.put("url", getServerIPPort(request) + context_path + imagePath + fileName);
        map.put("url", context_path + imagePath + fileName);
        map.put("origname", origName);
        //保存到数据库
        StudentFileBean fileBean = getEntityFromRequest(StudentFileBean.class);
        fileBean.setFilename(fileName);
        fileBean.setUrl(context_path + imagePath + fileName);
        fileBean.setOrigname(origName);
        fileBean.setEndtime(endtime);
        fileBean.setTimetable_id(timetable_id);
        fileBean.setStudent_id(student_id);
        fileService.addStudentFile(fileBean);

        result.setCode(SystemStatusEnum.SUCCESS.getCode());
        result.setMessage("上传成功");
        result.setData(map);
        return result;
    }
    /*
     *采用spring提供的上传文件的方法
     */
    @ApiOperation(value = "多个文件上传", nickname = "xxxx", notes = "多文件上传接口")
    @RequestMapping(value = "springUploadMore", method = {RequestMethod.POST})
    public BaseResponse springUploads(@RequestParam("file") MultipartFile[] files) throws IOException {
        List<Map<String, String>> list = new ArrayList<>();
        BaseResponse result = new BaseResponse();

        if (files!=null) {
            for(int i=0; i<files.length; i++){
                Map<String, String> map = new HashMap<>();
                MultipartFile file = files[i];
                String origName = file.getOriginalFilename();
                long startTime = System.currentTimeMillis();
                System.out.println("fileName：" + file.getOriginalFilename() + "==" + file.getContentType());
                String fileName = "file_" + new Date().getTime() + origName.substring(origName.indexOf("."), origName.length());

                String path = this.path + fileName;

                System.out.println("path="+path);

                File file1 = new File(this.path);
                if (!file1.exists()) {
                    boolean end = file1.mkdirs();
                    System.out.println("end=" + end);
                }
                File newFile = new File(path);
                if (!newFile.exists()) {
                    newFile.createNewFile();
                }
                file.transferTo(newFile);

                System.out.println("filePath=" + newFile.getPath());
                long endTime = System.currentTimeMillis();
                System.out.println("方法二的运行时间：" + String.valueOf(endTime - startTime) + "ms");
                map.put("filename", fileName);
                map.put("url", getServerIPPort(request) + context_path + imagePath + fileName);

                list.add(map);
            }
        }
        result.setCode(SystemStatusEnum.SUCCESS.getCode());
        result.setMessage("上传成功");
        result.setData(list);
        return result;
    }

    /**
     * 获取服务部署根路径 http:// + ip + port
     *
     * @param request
     * @return
     */
    private String getServerIPPort(HttpServletRequest request) {
//        return request.getScheme() + "://" + "169.254.41.98" + ":" + request.getServerPort();
        return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
    }

    /**
     * @param fileName 文件名
     * @return
     */
    @ApiOperation(value = "文件下载", nickname = "xxxx", notes = "文件下载")
    @RequestMapping(value = "/download", method = {RequestMethod.POST, RequestMethod.GET})
    public void download(@RequestParam(name = "fileName", required = true) String fileName,
                           HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取输出流
        OutputStream stream = response.getOutputStream();
        try {
            String PANFU = path;//文件保存盘符
            //清空下载文件的空白行（空白行是因为有的前端代码编译后产生的）
            response.reset();
            //设置响应头，把文件名字设置好
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            //解决编码问题
            response.setContentType("application/octet-stream; charset=utf-8");
//            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);

            //创建存储的文件对象（文件存储的路径和文件名字）
            File targetFile = new File(PANFU, fileName);
            //输出流开始写出文件（FileUtils是Apache下的工具类可以直接调用）
            stream.write(FileUtils.readFileToByteArray(targetFile));
            //刷新流
            stream.flush();
        } finally {
            //关闭流
            stream.close();
        }
    }

}
